#include <stdio.h>

#include <string.h>
#include <sys/param.h>
#include <stdlib.h>
#include <ctype.h>
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"

#include "esp_tls.h"
#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
#include "esp_crt_bundle.h"
#endif

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include <string.h>
#include <stdlib.h>
#include <sys/cdefs.h>
#include <inttypes.h>
#include "cJSON.h"
#include "esp_log.h"



#define MAX_HTTP_RECV_BUFFER 512
#define MAX_HTTP_OUTPUT_BUFFER 2048
static const char *TAG = "HTTP_CLIENT";

#include "du_http_client.h"

bool is_recording_file = true;
//"/spiffs/recorded_audio.pcm"
static void recording_audio(const char *file_name,char *data, int data_len)
{
    FILE *f = fopen(file_name, "wb");
    if (f == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for writing");
    }

    // Write binary data to the file
    size_t bytes_written = fwrite(data, 1, data_len, f);
    if (bytes_written != data_len)
    {
        ESP_LOGE(TAG, "Failed to write entire data to file");
        fclose(f);
    }

    // Close the file
    fclose(f);
    ESP_LOGI(TAG, "Binary data saved to file");

}



#define MAX_DATA_SIZE 1024  // 根据你的需求设置合适的数据大小
// 封装文件读取和发送函数
static size_t read_file_and_send_data(const char *file_name, esp_http_client_handle_t client) {
    FILE* file = fopen(file_name, "rb");
    if (file == NULL) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return 0;
    }

    char buffer[MAX_DATA_SIZE];
    size_t total_bytes_sent = 0;
    size_t bytes_read;

    while ((bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file)) > 0) {
        int wlen = esp_http_client_write(client, buffer, bytes_read);
        if (wlen < 0) {
            ESP_LOGE(TAG, "Write failed");
        }
        total_bytes_sent += bytes_read;
    }

    fclose(file);

    return total_bytes_sent;
}
char *stt_request(const char *url, const char *query,esp_http_client_method_t method, const char *content_type, char *data, size_t data_len)
{
    esp_http_client_config_t config = {
        .url = url,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);

    char *output_buffer = NULL;

    // Allocate memory for output buffer
    output_buffer = malloc(MAX_HTTP_OUTPUT_BUFFER + 1);
    if (output_buffer == NULL) {
        ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
        free(url);
        return NULL;
    }
    // POST Request
    esp_http_client_set_method(client, method);
    esp_http_client_set_header(client, "Content-Type", content_type);
    esp_err_t err = esp_http_client_open(client, data_len);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
    } else {

        read_file_and_send_data("/spiffs/demo.pcm", client);
        esp_http_client_fetch_headers(client);
        int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
        if (data_read >= 0) {
            output_buffer[data_read] = '\0'; // Null-terminate the string
            ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %" PRId64,
                     esp_http_client_get_status_code(client),
                     esp_http_client_get_content_length(client));
            ESP_LOG_BUFFER_HEX(TAG, output_buffer, data_read);
        } else {
            ESP_LOGE(TAG, "Failed to read response");
        }
    }

    esp_http_client_cleanup(client);
    free(url);
    return output_buffer;
}

char *chat_request(const char *url, const char *query,esp_http_client_method_t method, const char *content_type, char *data, size_t data_len)
{
    esp_http_client_config_t config = {
        .url = url,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);

    char *output_buffer = NULL;

    // Allocate memory for output buffer
    output_buffer = malloc(MAX_HTTP_OUTPUT_BUFFER + 1);
    if (output_buffer == NULL) {
        ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
        free(url);
        return NULL;
    }
    // POST Request
    esp_http_client_set_method(client, method);
    esp_http_client_set_header(client, "Content-Type", content_type);
    esp_err_t err = esp_http_client_open(client, data_len);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
    } else {
        int wlen = esp_http_client_write(client, data, data_len);
        if (wlen < 0) {
            ESP_LOGE(TAG, "Write failed");
        }
        esp_http_client_fetch_headers(client);
        int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
        if (data_read >= 0) {
            output_buffer[data_read] = '\0'; // Null-terminate the string
            ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %" PRId64,
                     esp_http_client_get_status_code(client),
                     esp_http_client_get_content_length(client));
            ESP_LOG_BUFFER_HEX(TAG, output_buffer, data_read);
        } else {
            ESP_LOGE(TAG, "Failed to read response");
        }
    }

    esp_http_client_cleanup(client);
    free(url);
    return output_buffer;
}

#define MAX_CONTENT_LENGTH 1024
void tts_request(const char *url, const char *query,esp_http_client_method_t method, const char *content_type, char *data, size_t data_len)
{
    esp_http_client_config_t config = {
        .url = url,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);

    char *output_buffer = NULL;

    // Allocate memory for output buffer
    output_buffer = malloc(MAX_HTTP_OUTPUT_BUFFER + 1);
    if (output_buffer == NULL) {
        ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
        free(url);
    }
    // POST Request
    esp_http_client_set_method(client, method);
    esp_http_client_set_header(client, "Content-Type", content_type);
    esp_err_t err = esp_http_client_open(client, data_len);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
    } else {
        int wlen = esp_http_client_write(client, data, data_len);
        if (wlen < 0) {
            ESP_LOGE(TAG, "Write failed");
        }
        esp_http_client_fetch_headers(client);
        int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
        if (data_read >= 0) {
            output_buffer[data_read] = '\0'; // Null-terminate the string
            ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %" PRId64,
                     esp_http_client_get_status_code(client),
                     esp_http_client_get_content_length(client));
            ESP_LOG_BUFFER_HEX(TAG, output_buffer, data_read);
        } else {
            ESP_LOGE(TAG, "Failed to read response");
        }
    }

    esp_http_client_cleanup(client);
    free(url);
    if (is_recording_file)
    {
        recording_audio("/spiffs/recorded_audio.pcm",output_buffer,MAX_CONTENT_LENGTH - 1);

    }
    else
    {
        // return output_buffer;

    }


}





void test_http_client()
{

    char * sk_api = "app_id=***&api_key=**********&api_secrt=*************";
    char * data = "hello";
    
    char *response = chat_request("https://127.0.0.1:8000", "/chat" , HTTP_METHOD_POST, "application/json", data, strlen(data));
    if (response != NULL) {
        // Process or use the response data
        printf("Response: %s\n", response);
        free(response); // Free allocated memory for response when done
    } else {
        // Handle error
        printf("Failed to fetch data from server\n");
    }


}